package com.sheng.project.study.proxy;

import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author liusheng
 * @date 2023/06/29
 */
public class ProxyTest {

    @Test
    public void m1() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取接口对应的代理类
        Class<IService> proxyClass = (Class<IService>) Proxy.getProxyClass(IService.class.getClassLoader(), IService.class);
        // 创建代理类的处理器
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("我是 InvocationHandler，被调用的方法是：" + method.getName());
                return null;
            }
        };
        // 创建代理实例
        IService iService = proxyClass.getConstructor(InvocationHandler.class).newInstance(invocationHandler);
        // 调用代理的方法
        iService.m1();
        iService.m1();
        iService.m1();
    }

    @Test
    public void m2() {
        // 创建代理类的处理器
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("我是 InvocationHandler，被调用的方法是：" + method.getName());
                return null;
            }
        };
        // 创建代理类的实例
        IService iService = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[]{IService.class}, invocationHandler);
        // 调用代理类的方法
        iService.m1();
        iService.m2();
        iService.m3();
    }

    @Test
    public void costTimeProxy() {
        IService serviceA = CostTimeInvocationHandler.createProxy(new ServiceA(), IService.class);
        IService serviceB = CostTimeInvocationHandler.createProxy(new ServiceB(), IService.class);
        serviceA.m1();
        serviceA.m2();
        serviceA.m3();
        serviceB.m1();
        serviceB.m2();
        serviceB.m3();
    }

    @Test
    public void userService() {
        // 后续当我们创建一个新的接口的时候，不需要再去新建一个代理类了，只需要使用CostTimeInvocationHandler.createProxy创建一个新的代理对象就可以了
        IUserService userService = CostTimeInvocationHandler.createProxy(new UserService(), IUserService.class);
        userService.insert("黄金鹏");
    }
}
